-module(cons).
-export([cons/2,atomp/1,car/1,cdr/1,list/1]).

rpc(Pid, Request) ->    
    Pid ! {self(), Request},
    receive
	{Pid, Response} ->
	    Response
    end.

% consアクタ
cons(X,Y) ->
    receive
	% atomp メッセージに false と返事する.
	{Cont, atomp} ->
	    Cont ! {self(),false},
	    cons(X,Y);
	% car メッセージに X と返事する.
	{Cont, car} ->
	    Cont ! {self(),X},
	    cons(X,Y);
	% cdr メッセージに Y と返事する. リストの場合は Y にプロセスIDが入っている.
	{Cont, cdr} ->
	    Cont ! {self(),Y},
	    cons(X,Y)
    end.

% アクタにメッセージを送る関数.
atomp(X) -> rpc(X, atomp).
car(X)   -> rpc(X, car).
cdr(X)   -> rpc(X, cdr).

% consアクタを連ねてリストを作る関数.
list([])    -> null;
list([X|Y]) -> spawn(fun() -> cons(X,list(Y)) end).

